<?php


namespace App\Http\Controllers\Saas;


use App\Http\Controllers\Controller;
use App\Http\Resources\PaginationCollection;
use App\Http\Service\DeviceService;
use App\Model\AreasPrice;
use App\Model\Bill;
use App\Model\Business;
use App\Model\BusinessConf;
use App\Model\Contract;
use App\Model\Device;
use App\Model\DeviceLog;
use App\Model\DeviceOffLog;
use App\Model\DevicePowerLog;
use App\Model\DeviceWarning;
use App\Model\Order;
use App\Model\Rate;
use App\Model\Repair;
use App\Model\TestRecord;
use App\User;
use App\Utils\Result;
use App\Utils\Token;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redis;
use PhpParser\Node\Stmt\Return_;

class DeviceController extends Controller
{
    public function index(Request $request)
    {
        // Get the current page number from the request parameters (default to 1)
        $page = $request->input('page', 1);

        // Get the number of houses to show per page
        $perPage = $request->input('pageSize', 20);
        $sn = $request->input('sn');
        $mac = $request->input('mac');
        $name = $request->input('name');
        $iccid = $request->input('iccid');
        $bus_type = $request->input('bus_type');
        $onlineStatus = $request->input('onlineStatus');
        $mobile = $request->input('mobile');
        $recharge = $request->input('recharge_disabled');
        $warning= $request->input('is_warning');
        $pay_type = $request->input('pay_type');
        $type = $request->input('type');
        $business_show = $request->input('business_show');
        $client_id = $request->input('client_id');
        $query = Device::query();
        $user = $this->getUser();
        if($user->roles != 'admin' && (!$mobile && !$sn)){
            return Result::success([]);
        }
        if($recharge != ''){
            $query->where('recharge_disabled', $recharge);
        }
        if($warning != ''){
            $query->where('is_warning', $warning);
        }
        if($type){
            $query->where('type', $type);
        }
        if($pay_type != ''){
            $query->where('pay_type', $pay_type);
        }
        if($business_show != ''){
            $query->where('business_show', $business_show);
        }
        if($bus_type != ''){
            $query->where('bus_type', $bus_type);
        }
        if ($onlineStatus == 1) {
            $query->where('online_status', 1);
        }
        if ($onlineStatus == 2) {
            $query->where('online_status', '<>', 1);
        }
        if ($onlineStatus == 3) {
            $query->where('house_id', '>', 0);
        }
        if ($sn) {
            $query->where('sn','like', '%'.$sn.'%');
        }
        if($mobile){
            $business =User::query()->where('mobile','like','%'.$mobile.'%')->with('business')->first();
            $busId = $business->business->id;
            $query->where('business_id',$busId);
        }
        if ($mac) {
            $query->where('mac','like', '%'.$mac.'%');
        }
        if ($name) {
            $query->where('name', 'like','%'.$name.'%');
        }
        if ($iccid) {
            $query->where('iccid', 'like','%'.$iccid.'%');
        }
        if($client_id){
            $query->where('client_id', $client_id);
        }

        $data = $query->with('house', 'business')
            ->with('business.user')
            ->withCount('offLog')
            ->orderByDesc('id')
            ->paginate($perPage, ['*'], 'page', $page);
        return Result::success(new PaginationCollection($data));
    }



    public function trouble(Request $request)
    {
        // Get the current page number from the request parameters (default to 1)
        $page = $request->input('page', 1);

        // Get the number of houses to show per page
        $perPage = $request->input('pageSize', 20);
        $money = $request->input('money');

        $query = Device::query();

        if ($money) {
            $query->where('month_recharge','>=', $money);
        }
//        if ($du) {
//            $query->where('du', '>=',$du);
//        }
        $data = $query->with('house', 'business')
            ->withCount('offLog')
            ->orderByDesc('month_recharge')
            ->paginate($perPage, ['*'], 'page', $page);
        $firstDayOfMonth = date('Y-m-01 00:00:00');
        $lastDayMonth = date('Y-m-t 23:59:59');
        foreach($data as &$v){
            $v['month'] = DevicePowerLog::query()->where('created_at','>=',$firstDayOfMonth)
                ->where('created_at','<=',$lastDayMonth)
                ->where('device_id',$v['id'])
                ->sum('xh');
            if($v['month'] > 0){
                $v['month'] = round($v['month']/1000,2);
            }
        }
        return Result::success(new PaginationCollection($data));
    }

    public function detail($id)
    {
        $res = Device::with('house')->find($id);

        return Result::success($res);
    }

    public function clearMonth(){
        Device::query()->update(['month_recharge'=>0]);
    }

    public function update(Request $request, $id)
    {
        $deviceModel = Device::where('id', $id)->first();
        $data = $request->all();
//        if($data['is_master'] == 0){
//            $data['net_type'] = 2;
//
//         }else{
//            $data['net_type'] = 1;
//        }
        $normalStr= '[联网模式由';
        $typeStr = $deviceModel->is_master== 1?'主表':'从表';
        $typeStr1= $data['is_master']== 1?'主表':'从表';
        $typeStr = $normalStr.$typeStr.'调整为'.$typeStr1.']';
        $dateStr = '[到期时间由'.$deviceModel->expired_at.'调整为'.$data['expired_at'].']';
        $agentStr = '[厂商由'.$deviceModel->agent_id.'调整为'.$data['agent_id'].']';
        $normalStr = '[限制充值由';
        $disStr = '[限制充值由'.$deviceModel->recharge_disabled == 1?'开启':'关闭';
        $disStr1= $data['recharge_disabled'] == 1?'开启':'关闭';
        $disStr = $normalStr.$disStr.'调整为'.$disStr1.']';
        $monthStr = '[月充值额度由'.$deviceModel->month_limit.'调整为'.$data['month_limit'].']';
        $speedStr = '[速度由'.$deviceModel->speed.'调整为'.$data['speed'].']';
        $deviceModel->fill($data);
        $deviceModel->save();
        $deviceModel->load('house', 'business');

        if ($request->input('speed') && $request->input('speed') != $deviceModel->speed) {
            $service = app()->make(DeviceService::class);
            $service->speed($deviceModel->mac, $request->input('speed', 1));
        }
        $save['action'] = 9;
        $save['device_id'] = $id;
        $save['user_name'] = $this->getUser()->mobile;
        $save['log'] = $deviceModel->sn.$typeStr.$disStr.$monthStr.$agentStr.$speedStr.$dateStr;
        DeviceLog::create($save);
        return Result::success($deviceModel);
    }

    public function destroy($id)
    {
        $deviceModel = Device::query()->find($id);
        if ($deviceModel) {
            TestRecord::query()->where('sn',$deviceModel->sn)->delete();
            $deviceModel->delete();
        }
        return Result::success();
    }

    public function setTotal(Request $request,$id)
    {
        $value = $request->input('value');
        $deviceModel = Device::where('id', $id)->first();
        if (!$deviceModel) {
            return Result::error(404, '设备不存在');
        }
        $service = app()->make(DeviceService::class);
        if($deviceModel->online_status != 1){
            return Result::error(500,'只可修改在线设备');
        }
        $service->setTotal($deviceModel->mac,$value);
        return Result::success();
    }

    public function setMode(Request $request)
    {
        $type = $request->input('type');
        $service = app()->make(DeviceService::class);
        $service->setMode($request->input('mac'), $type);
        $device = Device::query()->where('mac', $request->input('mac'))->first(['sn', 'pay_type', 'online_status', 'signal']);
        if($device->online_status != 1){
            return Result::error(500,'只可修改在线设备');
        }
        sleep(6);
        $device = Device::query()->where('mac', $request->input('mac'))->first(['sn', 'pay_type', 'online_status', 'signal']);
        if($device->pay_type == $type){
            return Result::success($device);
        }else{
            $service->setMode($request->input('mac'), $type);
            sleep(6);
            $device = Device::query()->where('mac', $request->input('mac'))->first(['sn', 'pay_type', 'online_status', 'signal']);
            if($device->pay_type == $type){
                return Result::success($device);
            }
        }
        return Result::error(1001,'5秒后确认模式未成功，请再次点击确认');
    }

    # 拉闸
    public function stop(Request $request, $id)
    {
        $deviceModel = Device::where('id', $id)->first();
        if (!$deviceModel) {
            return Result::error(404, '设备不存在');
        }
        $service = app()->make(DeviceService::class);
        $result = $service->stop($deviceModel->mac);

        return Result::success();
    }

    # 合闸
    public function start(Request $request, $id)
    {
        $deviceModel = Device::where('id', $id)->first();
        if (!$deviceModel) {
            return Result::error(404, '设备不存在');
        }
        $service = app()->make(DeviceService::class);
        $result = $service->start($deviceModel->mac);
        return Result::success();
    }

    public function curr(Request $request, $id){
        $deviceModel = Device::where('id', $id)->first();
        if (!$deviceModel) {
            return Result::error(404, '设备不存在');
        }
        $service = app()->make(DeviceService::class);
        $result = $service->warningCurr($deviceModel->mac, $request->input('warning_curr', 1));
        return Result::success();
    }

    # 清0
    public function clear(Request $request, $id)
    {
        $deviceModel = Device::where('id', $id)->first();
        if (!$deviceModel) {
            return Result::error(404, '设备不存在');
        }
        $service = app()->make(DeviceService::class);
        $result = $service->clear($deviceModel->mac);

        return Result::success();
    }

    # 调表
    public function speed(Request $request, $id)
    {
        $deviceModel = Device::where('id', $id)->first();
        if (!$deviceModel) {
            return Result::error(404, '设备不存在');
        }
        $service = app()->make(DeviceService::class);
        $result = $service->speed($deviceModel->mac, $request->input('speed', 1));

        return Result::success();
    }

    public function rateList()
    {
        $data = Rate::query()->get();
        return Result::success($data);
    }

    public function addRate(Request $request)
    {
        $rate = $request->input('rate');
        if (!$rate) {
            return Result::error(401, '参数错误');
        }
        Rate::create(['rate' => $rate, 'name' => $request->input('name')]);
        return Result::success();
    }

    public function updateRate(Request $request, $id)
    {
        if (!$request->input('rate')) {
            return Result::error(401, '参数错误');
        }
        $rate = Rate::query()->find($id);
        $rate->rate = $request->input('rate');
        $rate->name = $request->input('name');
        $rate->save();

        return Result::success();
    }

    public function powerLogData(Request $request)
    {
        $date = $request->input('date') ?? now()->toDateString();
        $startHour = $request->input('startHour') ?? '00';
        $endHour = $request->input('endHour') ?? '24';
        $deviceId = $request->input('deviceId');
        $device = Device::query()->find($deviceId);
        $data = [
            'label' => [],
            'data' => [],
            'device' => $device
        ];
        if ($date) {
            $now = new \DateTime($date);
        } else {
            $now = new \DateTime();
        }
        $startOfDay = clone $now;
        $startOfDay->setTime($startHour, 0, 0);
        $now->setTime($endHour, 59, 59);
        $i = $startHour;
        while ($startOfDay <= $now) {
            if ($i > $endHour) {
                break;
            }
            // 将当前小时的时间添加到数组中
            $tempArr = [];
            $tempArr['start'] = $startOfDay->format('Y-m-d H');
            // 移动到下一个小时
            $startOfDay->modify('+1 hour');
            $tempArr['end'] =$startOfDay->format('Y-m-d H');
            $cacheKey1 = str_replace('-', "", $tempArr['start']);
            $cacheKey = str_replace(' ', "", $cacheKey1);
            $key = $deviceId.'-'.$cacheKey;
            if(Redis::exists($key)){
                $tempArr['power'] = Redis::get($key);
                $data['data'][] =  $tempArr['power']/1000;
            }else{
                $tempArr['power'] = 0;
                $data['data'][] = 0;
            }
            $data['label'][] = $tempArr['start'];
            $i++;
        }
        return Result::success($data);
    }

    // 设备日志
    public function heartLog(Request $request)
    {
        $page = $request->input('page', 1);
        $perPage = $request->input('pageSize', 20);
        $sn = $request->input('sn');
        $time = $request->input('time');
        if($sn){
            $deviceId = Device::query()->where('sn', $sn)->value('id');
        }else{
             return Result::error(500,'因数据量过多，请输入设备号查询');
        }
        $query = DevicePowerLog::query();
        $data = $query->orderByDesc('id')
            ->where(function ($q) use ($time,$deviceId) {
                if($time){
                    $q->where('created_at','>=',$time[0]);
                    $q->where('created_at','<=',$time[1]);
                }else{
                    $start = date('Y-m-d H:i:s', strtotime('-2 day'));
                    $end = date('Y-m-d H:i:s');
                    $q->where('created_at','>=',$start);
                    $q->where('created_at','<=',$end);
                }
                $q->where('device_id',$deviceId);
            })
            ->paginate($perPage, ['*'], 'page', $page);
        return Result::success(new PaginationCollection($data));
    }

    // 设备日志
    public function log(Request $request)
    {
        $page = $request->input('page', 1);
        $perPage = $request->input('pageSize', 20);
        $action = $request->input('action');
        $sn = $request->input('sn');
        $time = $request->input('time');
        if($sn){
            $deviceId = Device::query()->where('sn', $sn)->value('id');
        }else{
            $deviceId = 0;
        }
        $query = DeviceLog::query();
        $data = $query->orderByDesc('id')
            ->where(function ($q) use ($action,$time,$deviceId) {
                if ($action) {
                    $q->where('action', $action);
                }
                if($time){
                    $q->where('created_at','>=',$time[0]);
                    $q->where('created_at','<=',$time[1]);
                }
                if($deviceId){
                    $q->where('device_id',$deviceId);
                }
            })
            ->with('device')
            ->orderBy('created_at','desc')
            ->paginate($perPage, ['*'], 'page', $page);
        return Result::success(new PaginationCollection($data));
    }

    // 设备日志
    public function offlog(Request $request, $id)
    {
        $page = $request->input('page', 1);
        $perPage = $request->input('pageSize', 20);
        $query = DeviceOffLog::query();
        $data = $query->orderByDesc('id')
            ->where('device_id', $id)
            ->paginate($perPage, ['*'], 'page', $page);
        return Result::success(new PaginationCollection($data));
    }

    /**异常日志
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function warningLog(Request $request)
    {
        $page = $request->input('page', 1);
        $perPage = $request->input('pageSize', 20);
        $query = DeviceWarning::query();
        $sn = $request->input('sn');
        if($sn){
            $query->where('sn', $sn);
        }
        $data = $query->orderByDesc('id')
            ->paginate($perPage, ['*'], 'page', $page);
        return Result::success(new PaginationCollection($data));
    }

    /**恢复出场设置
     * @param $id
     * @return \Illuminate\Http\JsonResponse
     */
    public function cancel($id)
    {

        DeviceLog::query()->where('device_id', $id)->delete();
        DeviceOffLog::query()->where('device_id', $id)->delete();
        DevicePowerLog::query()->where('device_id', $id)->delete();
        Bill::query()->where('device_id', $id)->delete();
        Order::query()->where('device_id',$id)
            ->update(['deleted_at'=>date('Y-m-d H:i:s')]);
        $query = Device::query();
        $save['total_money'] = 0;
        $save['total_recharge'] = 0;
        $save['mobile'] = '';
        $save['total'] = 0;
        $save['business_id'] = 0;
        $save['house_id'] = 0;
        $save['du'] = 0;
        $save['total_du'] = 0;
        $save['recharge_disabled'] = 0;
        $save['month_recharge'] = 0;
        $save['price'] = null;
        $save['speed'] = 1000;
        $query->where('id', $id)->update($save);
        return Result::success();
    }

    /**获取统计电量
     * @param Request $request
     * @return void
     */
    public function powerList(Request $request)
    {
        $deviceId = $request->input('deviceId');
        $type = $request->input('type');
        $time = $request->input('date1');
        if ($type == 'day') {
            if ($time) {
                $now = new \DateTime($time);
            } else {
                $now = new \DateTime();
            }
            $startOfDay = clone $now;
            $startOfDay->setTime(0, 0, 0);
            $now->setTime(23, 59, 59);
            $data = [];
            $i = 0;
            $data['now_total'] = 0;
            while ($startOfDay <= $now) {
                if ($i > 24) {
                    break;
                }
                // 将当前小时的时间添加到数组中
                $tempArr = [];
                $data['keys'][] = $tempArr['start'] = $startOfDay->format('Y-m-d H');
                // 移动到下一个小时
                $startOfDay->modify('+1 hour');
                $tempArr['end'] =$startOfDay->format('Y-m-d H');
                $cacheKey1 = str_replace('-', "", $tempArr['start']);
                $cacheKey = str_replace(' ', "", $cacheKey1);
                $key =$deviceId.'-'.$cacheKey;
                if(Redis::exists($key)){
                    $tempArr['power'] = Redis::get($key);
                    $tempArr['power'] =  $data['data'][] =  $tempArr['power']/1000;
                    $data['table'][] = $tempArr;
                }else{
                    $tempArr['power'] = 0;
                    $data['data'][] = 0;
                }
                $data['now_total'] += $tempArr['power'];
                $i++;
            }
        } elseif ($type == 'month') {
            if ($time) {
                $dateStart = new \DateTime($time . "-01");
            } else {
                $dateStart = new \DateTime(date('Y-m') . "-01");
            }
//            $dateStart = str_replace("-", "",  $dateStart);
            $dateEnd = (clone $dateStart)->modify('first day of next month');
            $i = 0;
            $data = [];
            $data['now_total'] = 0;
            while ($dateStart < $dateEnd) {
                if ($i > 31) {
                    break;
                }
                $tempArr = [];
                $data['keys'][] = $tempArr['start'] = $dateStart->format('Y-m-d');
                $tempArr['end'] = $dateStart->modify('+1 day');
                $tempArr['end'] = $tempArr['end']->format('Y-m-d');
                $cacheKey1 = str_replace('-', "", $tempArr['start']);
                $cacheKey = str_replace(' ', "", $cacheKey1);
                $key =$deviceId.'-'.$cacheKey;
                if(Redis::exists($key)){
                    $tempArr['power'] = Redis::get($key);
                    $tempArr['power'] = $data['data'][] =  $tempArr['power']/1000;
                    $data['table'][] = $tempArr;
                }else{
                    $tempArr['power'] = 0;
                    $data['data'][] = 0;
                }
                $data['now_total'] += $tempArr['power'];
                $i++;
            }
        } else {
            $data = [];
            if ($time) {
                $year = $time;
            } else {
                $year = date('Y');
            }
            $data['now_total'] = 0;
            for ($month = 1; $month <= 12; $month++) {
                // 使用 str_pad() 确保月份有两位数字
                $formattedMonth = str_pad($month, 2, '0', STR_PAD_LEFT);
                $tempArr = [];
                $data['keys'][] = "$year-$formattedMonth";
                if ($month == 12) {
                    $tempArr['start'] =  $year . '-' . $month;
                    $tempArr['end'] = $year . '-' . $month;
                } else {
                    if($month < 10){
                        $month = '0'.$month;
                    }
                    $tempArr['start'] = $year . '-' . $month;
                    $tempArr['end'] = $year . '-' . ($month + 1);
                }
                $cacheKey1 = str_replace('-', "", $tempArr['start']);
                $cacheKey = str_replace(' ', "", $cacheKey1);
                $key =$deviceId.'-'.$cacheKey;
                if(Redis::exists($key)){
                    $tempArr['power'] = Redis::get($key);
                    $tempArr['power'] =  $data['data'][] =  $tempArr['power']/1000;
                    $data['table'][] = $tempArr;
                }else{
                    $data['data'][] = 0;
                    $tempArr['power'] = 0;
                }
                $data['now_total'] += $tempArr['power'];
            }
        }
        $data['all'] = $data['now_total'];
        return Result::success($data);
    }

    public function restart(Request $request)
    {
        $deviceModel = Device::where('mac', $request->input('mac'))->first();
        if (!$deviceModel) {
            return Result::error(404, '设备不存在');
        }
        $service = app()->make(DeviceService::class);
        $result = $service->restart($request->input('mac'));
        return Result::success();
    }

    public function makeFg(Request $request){
        $sn = $request->input('sn');
        $device = Device::query()->where('sn',$sn)->first();
        $data = $device->makeFg();
        if($data){
            $service = app()->make(DeviceService::class);
            $result = $service->sendFgb($device->mac,$data);
            return Result::success($result);
        }
        return Result::error(404,'请先设置峰谷参数');
    }


    public function setAdcode(Request $request){
        $adcode = $request->input('adcode');
        $deviceId = $request->input('device_id');
        if(!$deviceId || !$adcode){
            return Result::error(1001,'参数设备id或者省份code不可为空');
        }
        AreasPrice::where('device_id',$deviceId)->delete();
        $data =  AreasPrice::when(!empty($adcode), function ($query) use ($adcode) {
            $query->where('adcode', $adcode );
            $query->where('device_id',0);
        })
            ->with('area')
            ->orderBy('adcode')
            ->orderBy('season')
            ->orderBy('month')
            ->orderBy('start')
            ->get();
        if(!$data){
            return Result::error(1001,'请先设置该省份收费规则');
        }
        foreach ($data as $item) {
            $model = new AreasPrice();
            $model->device_id = $deviceId;
            $model->start = $item->start;
            $model->end = $item->end;
            $model->coef_type = $item->coef_type;
            $model->month = $item->month;
            $model->adcode = $item->adcode;
            $model->season = $item->season;
            $model->save();
        }
        return Result::success();
    }
    public function getLvPrice(Request $request){
        try{
            $adcode = $request->input('adcode');
            $deviceId = $request->input('device_id');
            $list = AreasPrice::when(!empty($adcode), function ($query) use ($adcode) {
                    $query->where('adcode', $adcode );
                    $query->where('device_id',0);
                })
                ->when(!empty($deviceId), function ($query) use ($deviceId) {
                    $query->where('device_id', $deviceId );
                })
                ->with('area')
                ->orderBy('adcode')
                ->orderBy('season')
                ->orderBy('month')
                ->orderBy('start')
                ->get();
            return Result::success($list);
        }catch (\Exception $e){
            return Result::error(1001,$e->getMessage().$e->getTraceAsString());
        }
    }

    public function createLvPrice(Request $request){
        try{
            $adcode =$request->input('adcode');
            $season = $request->input('season',1);
            if(!$adcode){
                return Result::error(404,'请先选择地区');
            }
            $adcode = json_decode($adcode,true);
            $months = $request->input('month');
            $months = json_decode($months,true);
            $data = $request->input('data');
            $data = json_decode($data,true);
            foreach($adcode as $ad){
                foreach($months as $month){
                    AreasPrice::query()->where('device_id',0)
                        ->where('adcode',$ad)
                        ->where('month',$month)->delete();
                    foreach ($data as $item) {
                        $model = new AreasPrice();
                        $model->business_id = 0;
                        $model->start = $item['start'];
                        $model->end = $item['end'];
                        $model->coef_type = $item['coef_type'];
                        $model->month = $month;
                        $model->adcode = $ad;
                        $model->season = $season;
                        $model->save();
                    }
                }
            }
            return Result::success();
        }catch (\Exception $e){
            return Result::error(1001,$e->getMessage().$e->getTraceAsString());
        }
    }


}
